using AutoMapper;
using MediatR;
using RBAC.Domain.Department;
using RBAC.Domain.Dto.Output;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Read.Api.Application.Command.ERP.MaterialFile.Department;
using System.Text;

namespace RBAC.Read.Api.Application.Handler.ERP.MaterialFile.Department
{
    /// <summary>
    /// 获取部门列表处理类
    /// </summary>
    public class GetDepartmentListHandler : IRequestHandler<GetDepartmentListCommand, APIPaging<GetDepartmentListDto>>
    {
        private readonly IBaseRepository<DepartmentManagement> departmentRepository;
        private readonly IMapper mapper;
        private readonly ILogger<GetDepartmentListHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="departmentRepository">部门仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetDepartmentListHandler(
            IBaseRepository<DepartmentManagement> departmentRepository,
            IMapper mapper,
            ILogger<GetDepartmentListHandler> logger)
        {
            this.departmentRepository = departmentRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 处理部门列表查询请求
        /// </summary>
        /// <param name="request">查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页部门数据</returns>
        public Task<APIPaging<GetDepartmentListDto>> Handle(GetDepartmentListCommand request, CancellationToken cancellationToken)
        {
            APIPaging<GetDepartmentListDto> res = new APIPaging<GetDepartmentListDto>();

            try
            {
                logger.LogInformation("开始获取部门列表，页码: {PageIndex}, 页大小: {PageSize}, 部门名称: {DepartmentName}, 状态: {Status}, 父级ID: {ParentId}",
                    request.PageIndex, request.PageSize, request.DepartmentName, request.Status, request.ParentId);

                // 构建查询条件
                StringBuilder whereClause = new StringBuilder("IsDeleted = false");
                var parameters = new Dictionary<string, object>();

                // 按部门名称模糊查询
                if (!string.IsNullOrEmpty(request.DepartmentName))
                {
                    whereClause.Append(" AND DepartmentName LIKE @DepartmentName");
                    parameters.Add("DepartmentName", $"%{request.DepartmentName}%");
                }

                // 按状态筛选
                if (request.Status.HasValue)
                {
                    whereClause.Append(" AND Status = @Status");
                    parameters.Add("Status", request.Status.Value);
                }

                // 根据父级ID查询子部门
                if (request.ParentId.HasValue)
                {
                    whereClause.Append(" AND ParentId = @ParentId");
                    parameters.Add("ParentId", request.ParentId.Value);
                }
                // 如果未指定ParentId，查询所有部门（不添加ParentId限制）

                // 添加排序条件
                string orderByClause = "Sort ASC, CreateTime DESC";

                // 使用自定义SQL查询Department表，而不是通过仓储自动映射
                var (data, totalCount) = QueryDepartmentPaged(
                    request.PageIndex,
                    request.PageSize,
                    whereClause.ToString(),
                    orderByClause,
                    parameters
                );

                // 映射实体到DTO
                var departmentDtos = mapper.Map<List<GetDepartmentListDto>>(data);

                res.Code = APIEnums.Success;
                res.PageDatas = departmentDtos;
                res.TotalCount = totalCount;
                res.Msg = "获取部门列表成功";

                logger.LogInformation("获取部门列表成功，共 {Count} 个部门", totalCount);
            }
            catch (Exception ex)
            {
                res.Code = APIEnums.Error;
                res.Msg = "获取部门列表失败";
                logger.LogError(ex, "获取部门列表失败: {Message}", ex.Message);
            }

            return Task.FromResult(res);
        }

        /// <summary>
        /// 使用自定义SQL查询Department表
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="whereClause">查询条件</param>
        /// <param name="orderBy">排序条件</param>
        /// <param name="parameters">参数</param>
        /// <returns>分页数据和总数</returns>
        private (List<DepartmentManagement> Data, int TotalCount) QueryDepartmentPaged(
            int pageIndex, 
            int pageSize, 
            string whereClause = "", 
            string orderBy = "", 
            Dictionary<string, object> parameters = null)
        {
            try
            {
                // 构建基础查询条件
                var baseWhere = "WHERE IsDeleted = false";
                if (!string.IsNullOrEmpty(whereClause))
                {
                    baseWhere += $" AND {whereClause}";
                }

                // 获取总数
                var countSql = $"SELECT COUNT(*) FROM Department {baseWhere}";
                var count = departmentRepository.QueryFirstOrDefault<int>(countSql, parameters);

                // 分页查询
                var offset = (pageIndex - 1) * pageSize;
                var defaultOrderBy = string.IsNullOrEmpty(orderBy) ? "ORDER BY Id DESC" : $"ORDER BY {orderBy}";
                var dataSql = $"SELECT * FROM Department {baseWhere} {defaultOrderBy} LIMIT {pageSize} OFFSET {offset}";
                var data = departmentRepository.Query<DepartmentManagement>(dataSql, parameters).ToList();

                return (data, count);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "自定义查询Department表失败");
                throw;
            }
        }
    }
}